class A:
    def spam(self, x):
        pass

    def foo(self):
        pass


class B1:
    """简单的代理"""

    def __init__(self):
        self._a = A()

    def spam(self, x):
        return self._a.spam()

    def foo(self):
        return self._a.foo()

    def bar(self):
        pass


class B2:
    """使用__getattr__的代理，代理方法比较多时候"""

    def __init__(self):
        self._a = A()

    def bar(self):
        pass

    def __getattr__(self, name):  # 直接通过这个方法代理
        '''这个方法在访问的attribute不存在的时候被调用'''
        return getattr(self._a, name)


#
b = B2()
b.bar()
b.spam(42)


class Proxy:
    def __init__(self, obj):
        self._obj = obj
    def __getattr__(self, name):
        print('getattr:',name)
        return getattr(self._obj,name)

    # Delegate attribute assignment 属性代理委托
    def __setattr__(self, name, value):
        if name.startswith('_'):
            super().__delattr__(name) # 删除该属性
        else:
            print('delattr:', name)
            delattr(self._obj,name) # 删除属性

class Spam:
    def __init__(self,x):
        self.x = x
    def bar(self,y):
        print('Spam.bar:', self.x, y)

class A:
    def spam(self, x):
        print('A.spam', x)
    def foo(self):
        print('A.foo')
# Create an instance
s = Spam(2)
# Create a proxy around it
p = Proxy(s)
# Access the proxy
print(p.x)  # Outputs 2
p.bar(3)  # Outputs "Spam.bar: 2 3"
p.x = 37  # Changes s.x to 37



class A1:
    def spam(self, x):
        print('A1.spam', x)
    def foo(self):
        print('A1.foo')

class C:
    def __init__(self):
        self._a = A1()
    def spam(self, x):
        print('B.spam', x)
        self._a.spam(x)
    def bar(self):
        print('B.bar')
    def __getattr__(self, name):
        return getattr(self._a, name)